const crypto = require('crypto');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const moment = require('moment');
const _ = require('lodash');
const logger = require('./logger');

require('dotenv').config();
/**
 * 检查空值
 */
function checkNull(checkstr) {
  if (!checkstr || checkstr === 'null' || checkstr === 'undefined') {
    return '';
  }
  return String(checkstr).trim();
}

/**
 * 校验签名
 */
function checkSign(data, sign) {
  if (!sign) return false;
  
  const key = '';
  const sortedData = _.sortBy(Object.entries(data), ([key]) => key);
  const str = sortedData.map(([k, v]) => `${k}=${v}`).join('&') + key;
  const newsign = crypto.createHash('md5').update(str).digest('hex');
  
  return sign === newsign;
}

/**
 * 校验邮箱
 */
function checkEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

/**
 * 校验密码
 */
function checkPass(pass) {
  // 必须包含字母、数字，长度6-20位
  const passRegex = /^(?=.*[A-Za-z])(?=.*[0-9])[a-zA-Z0-9~!@&%#_]{6,20}$/;
  return passRegex.test(pass);
}

/**
 * 校验手机号
 */
function checkMobile(mobile) {
  const mobileRegex = /^1[3-9]\d{9}$/;
  return mobileRegex.test(mobile);
}

/**
 * 生成随机数
 */
function random(length = 6, numeric = true) {
  if (numeric) {
    return Math.random().toString().slice(2, 2 + length);
  } else {
    const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz';
    let result = '';
    for (let i = 0; i < length; i++) {
      result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
  }
}

/**
 * 密码加密
 */
async function encryptPassword(password) {
  const saltRounds = 10;
  return await bcrypt.hash(password, saltRounds);
}

/**
 * 密码验证
 */
async function verifyPassword(password, hash) {
  return await bcrypt.compare(password, hash);
}

/**
 * 生成JWT Token
 */
function generateToken(payload) {
  return jwt.sign(payload, process.env.JWT_SECRET, {
    expiresIn: process.env.JWT_EXPIRES_IN || '7d'
  });
}

/**
 * 验证JWT Token
 */
function verifyToken(token) {
  try {
    return jwt.verify(token, process.env.JWT_SECRET || 'wanyue-education-jwt-secret-key-2024');
  } catch (error) {
    return null;
  }
}

/**
 * 获取当前时间戳
 */
function getMillisecond() {
  return Date.now();
}

/**
 * 格式化当前时间
 */
function formatNowDate() {
  return moment().format('YYYY-MM-DD HH:mm:ss');
}

/**
 * 计算年龄
 */
function getAge(birthDate) {
  if (!birthDate) return 0;
  return moment().diff(moment(birthDate), 'years');
}

/**
 * 处理文件大小
 */
function handleSize(size) {
  if (size < 1024) {
    return size + 'B';
  } else if (size < 1024 * 1024) {
    return (size / 1024).toFixed(2) + 'KB';
  } else if (size < 1024 * 1024 * 1024) {
    return (size / (1024 * 1024)).toFixed(2) + 'MB';
  } else {
    return (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB';
  }
}

/**
 * 生成MD5
 */
function md5(str) {
  return crypto.createHash('md5').update(str).digest('hex');
}

/**
 * 加密字符串
 */
function encryption(code) {
  const key = 'wanyue_education_2024';
  const cipher = crypto.createCipher('aes-256-cbc', key);
  let encrypted = cipher.update(code, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

/**
 * 解密字符串
 */
function decrypt(code) {
  try {
    const key = 'wanyue_education_2024';
    const decipher = crypto.createDecipher('aes-256-cbc', key);
    let decrypted = decipher.update(code, 'hex', 'utf8');
    decrypted += decipher.final('utf8');
    return decrypted;
  } catch (error) {
    logger.error('解密失败:', error);
    return '';
  }
}

/**
 * 处理字符串长度
 */
function handleLength(str, type = 0) {
  if (!str) return '';
  
  if (type === 0) {
    // 按字符长度截取
    return str.length > 20 ? str.substring(0, 20) + '...' : str;
  } else {
    // 按字节长度截取
    const bytes = Buffer.byteLength(str, 'utf8');
    return bytes > 40 ? str.substring(0, 20) + '...' : str;
  }
}

/**
 * 生成订单号
 */
function generateOrderNo() {
  const timestamp = Date.now().toString();
  const random = Math.random().toString().slice(2, 8);
  return `WY${timestamp}${random}`;
}

/**
 * 成功响应
 */
function success(data = null, message = '操作成功') {
  return {
    code: 200,
    message,
    data
  };
}

/**
 * 错误响应
 */
function error(message = '操作失败', code = 400) {
  return {
    code,
    message
  };
}

/**
 * 分页响应
 */
function paginateResponse(data, total, page, limit) {
  return {
    code: 200,
    message: '获取成功',
    data: {
      list: data,
      total,
      page: parseInt(page),
      limit: parseInt(limit),
      total_pages: Math.ceil(total / limit)
    }
  };
}

/**
 * 分页参数处理
 */
function paginate(page, limit) {
  const pageNum = parseInt(page) || 1;
  const limitNum = parseInt(limit) || 10;
  const offset = (pageNum - 1) * limitNum;
  
  return {
    offset,
    limit: limitNum
  };
}

/**
 * 生成随机字符串
 */
function generateRandomString(length = 32) {
  return crypto.randomBytes(length).toString('hex');
}

/**
 * 生成订单号
 */
function generateOrderNo() {
  const timestamp = Date.now().toString();
  const random = Math.random().toString().slice(2, 8);
  return `ORDER${timestamp}${random}`;
}

/**
 * 密码加密
 */
async function hashPassword(password) {
  const saltRounds = 12;
  return await bcrypt.hash(password, saltRounds);
}

/**
 * 密码验证
 */
async function verifyPassword(password, hash) {
  return await bcrypt.compare(password, hash);
}


/**
 * 数据验证
 */
function validate(data, rules) {
  const errors = {};
  
  for (const [field, rule] of Object.entries(rules)) {
    const value = data[field];
    
    if (rule.required && (!value || value === '')) {
      errors[field] = `${field}不能为空`;
      continue;
    }
    
    if (value && rule.minLength && value.length < rule.minLength) {
      errors[field] = `${field}长度不能少于${rule.minLength}个字符`;
    }
    
    if (value && rule.maxLength && value.length > rule.maxLength) {
      errors[field] = `${field}长度不能超过${rule.maxLength}个字符`;
    }
    
    if (value && rule.pattern && !rule.pattern.test(value)) {
      errors[field] = `${field}格式不正确`;
    }
    
    if (value && rule.type) {
      if (rule.type === 'email' && !isValidEmail(value)) {
        errors[field] = `${field}邮箱格式不正确`;
      }
      if (rule.type === 'phone' && !isValidPhone(value)) {
        errors[field] = `${field}手机号格式不正确`;
      }
    }
  }
  
  return {
    isValid: Object.keys(errors).length === 0,
    errors
  };
}

/**
 * 邮箱验证
 */
function isValidEmail(email) {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

/**
 * 手机号验证
 */
function isValidPhone(phone) {
  const phoneRegex = /^1[3-9]\d{9}$/;
  return phoneRegex.test(phone);
}

/**
 * 文件大小格式化
 */
function formatFileSize(bytes) {
  if (bytes === 0) return '0 Bytes';
  
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

/**
 * 时间格式化
 */
function formatDate(date, format = 'YYYY-MM-DD HH:mm:ss') {
  const d = new Date(date);
  
  const year = d.getFullYear();
  const month = String(d.getMonth() + 1).padStart(2, '0');
  const day = String(d.getDate()).padStart(2, '0');
  const hours = String(d.getHours()).padStart(2, '0');
  const minutes = String(d.getMinutes()).padStart(2, '0');
  const seconds = String(d.getSeconds()).padStart(2, '0');
  
  return format
    .replace('YYYY', year)
    .replace('MM', month)
    .replace('DD', day)
    .replace('HH', hours)
    .replace('mm', minutes)
    .replace('ss', seconds);
}

/**
 * 相对时间
 */
function timeAgo(date) {
  const now = new Date();
  const past = new Date(date);
  const diff = now - past;
  
  const seconds = Math.floor(diff / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);
  const months = Math.floor(days / 30);
  const years = Math.floor(months / 12);
  
  if (years > 0) return `${years}年前`;
  if (months > 0) return `${months}个月前`;
  if (days > 0) return `${days}天前`;
  if (hours > 0) return `${hours}小时前`;
  if (minutes > 0) return `${minutes}分钟前`;
  return '刚刚';
}

/**
 * 数组去重
 */
function uniqueArray(arr, key = null) {
  if (key) {
    const seen = new Set();
    return arr.filter(item => {
      const value = item[key];
      if (seen.has(value)) {
        return false;
      }
      seen.add(value);
      return true;
    });
  }
  return [...new Set(arr)];
}

/**
 * 深拷贝
 */
function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (obj instanceof Date) return new Date(obj.getTime());
  if (obj instanceof Array) return obj.map(item => deepClone(item));
  if (typeof obj === 'object') {
    const clonedObj = {};
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key]);
      }
    }
    return clonedObj;
  }
}

module.exports = {
  checkNull,
  checkSign,
  checkEmail,
  checkPass,
  checkMobile,
  random,
  encryptPassword,
  verifyPassword,
  generateToken,
  verifyToken,
  getMillisecond,
  formatNowDate,
  getAge,
  handleSize,
  md5,
  encryption,
  decrypt,
  handleLength,
  generateOrderNo,
  success,
  error,
  paginate,
  paginateResponse,
  generateRandomString,
  hashPassword,
  validate,
  isValidEmail,
  isValidPhone,
  formatFileSize,
  formatDate,
  timeAgo,
  uniqueArray,
  deepClone
}; 